package models

import (
	"database/sql"
	"errors"
	"go.uber.org/zap"
	"reflect"
	"web_app/dao/mysql"
	"web_app/pak/jwt"
	"web_app/tool"
)

type User struct {
	Id        int64  `db:"id"`
	UserID    int64  `db:"user_id"`
	UserName  string `db:"username,omitempty"`
	Email     string `db:"email,omitempty"`
	Password  string `db:"password,omitempty"`
	CreatedAt string `db:"created_at,omitempty"`
	UpdatedAt string `db:"updated_at,omitempty"`
	Avatar    string `db:"avatar,omitempty"`
}

type UserList struct {
	UsersList []User `json:"usersList"`
	Total     int64
}

func (u User) IsEmpty() bool {
	return !reflect.DeepEqual(u, User{})
}

func (u User) CheckUserExist(username string) bool {
	user := u.GetUserByUserName(username)
	return user.IsEmpty()
}

func (u User) GetUserByUserName(userName string) (user User) {
	sqlStr := "select * from users where username = ?"
	_ = mysql.Db.Get(&user, sqlStr, userName)
	return user
}

func (u User) InsertUser() error {
	sqlStr := "insert into users (id,user_id,username,email,password,created_at,updated_at) values(:id,:user_id,:username,:email,:password,:created_at,:updated_at)"
	_, err := mysql.Db.NamedExec(sqlStr, u)
	if err != nil {
		zap.L().Error(" InsertUser() error", zap.Error(err))
		return err
	}
	return nil
}

func (u User) Login() (err error, token string) {
	oPassword := u.Password
	sqlStr := "select user_id, username, password,email,id from users where username = ?"

	err = mysql.Db.Get(&u, sqlStr, u.UserName)
	if err == sql.ErrNoRows {
		return errors.New("用户或密码错误"), token
	}

	if err != nil {
		return errors.New("未知错误"), token
	}

	if tool.EncryptPassword(oPassword) != u.Password {
		return errors.New("密码不正确"), token
	}
	Token, err := jwt.GenToken(u.UserID, u.UserName)
	if err != nil {
		return errors.New("登陆失败，请联系管理员"), token
	}
	return nil, Token
}

func (u User) GetUserInfoByUserId(userName int64) (user User, err error) {
	sqlStr := "select * from users where user_id = ?"
	err = mysql.Db.Get(&user, sqlStr, userName)
	if err != nil {
		return
	}
	return
}
func (u User) GetUserTotal() (total int64) {
	sqlStr := "select count(1) from users"
	err := mysql.Db.Get(&total, sqlStr)
	if err != nil {
		return 0
	}

	return
}

func (u User) GetUserList(param *ParamList) (usersList UserList, err error) {
	sqlStr := "select user_id,username,email,created_at from users limit ?,?"
	err = mysql.Db.Select(&usersList.UsersList, sqlStr, (param.Page-1)*param.Size, param.Size)
	usersList.Total = User{}.GetUserTotal()
	if err != nil {
		return
	}
	return
}
